package cn.jingyuan.owl.utils.core.comparator;

import cn.jingyuan.owl.utils.core.ClassUtils;
import cn.jingyuan.owl.utils.core.ObjectUtils;
import cn.jingyuan.owl.utils.core.ReflectUtils;
import cn.jingyuan.owl.utils.core.StringUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Comparator;

/**
 * Bean 字段排序器<br>
 * 参阅  PropertyComparator
 *
 * @param <T> 被比较的 Bean
 */
public class FieldComparator<T> implements Comparator<T>, Serializable {

    private final Field field;

    /**
     * 构造
     *
     * @param beanClass Bean 类
     * @param fieldName 字段名
     */
    public FieldComparator(Class<T> beanClass, String fieldName) {
        this.field = ClassUtils.getDeclaredField(beanClass, fieldName);
        if (this.field == null) {
            throw new IllegalArgumentException(StringUtils.format("field [{}] not found in Class [{}]", fieldName, beanClass.getName()));
        }
    }

    @Override
    public int compare(T o1, T o2) {
        if (o1 == o2) {
            return 0;
        } else if (null == o1) {
            // null 排在后面
            return 1;
        } else if (null == o2) {
            return -1;
        }

        Comparable<?> v1;
        Comparable<?> v2;
        try {
            v1 = (Comparable<?>) ReflectUtils.getFieldValue(o1, this.field);
            v2 = (Comparable<?>) ReflectUtils.getFieldValue(o2, this.field);
        } catch (Exception e) {
            throw new ComparatorException(e);
        }

        return compare(o1, o2, v1, v2);
    }


    private int compare(T o1, T o2, Comparable fieldValue1, Comparable fieldValue2) {
        int result = ObjectUtils.compare(fieldValue1, fieldValue2);
        if (0 == result) {
            // 避免 TreeSet / TreeMap 过滤掉排序字段相同但是对象不相同的情况
            result = CompareUtils.compare(o1, o2, true);
        }
        return result;
    }

}
